package com.example.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import com.example.dto.FileDTO;
import com.example.dto.ResultDTO;
import com.example.exception.CustomizeErrorCode;
import com.example.exception.CustomizeException;
import com.example.model.UserInfo;
import com.example.service.UploadService;
import com.example.upload.config.OSSProperties;
import com.example.utils.authUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;


@Service
@Slf4j
public class UploadServiceImpl implements UploadService {
    @Autowired
    private OSSProperties properties;
    @Autowired
    private OSS client;
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 到本地服务器获取标签
     *
     * @return
     */
    @Override
    public Map<String, String> signature() {
        String accessId = properties.getAccessId(); // 请填写您的AccessKeyId。
        String accessKey = properties.getAccessKey(); // 请填写您的AccessKeySecret。
        String endpoint = properties.getEndpoint(); // 请填写您的 endpoint。
        String bucket = properties.getBucket(); // 请填写您的 bucketname 。
        String host = properties.getHost(); // host的格式为 bucketname.endpoint
        // callbackUrl为 上传回调服务器的URL，请将下面的IP和Port配置为您自己的真实信息。
        String callbackUrl = "";
        String dir = properties.getDir(); // 用户上传文件时指定的前缀。

        try {
            long expireTime = properties.getExpireTime();
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessId", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime));
            // respMap.put("expire", formatISO8601Date(expiration));
            return respMap;

        } catch (Exception e) {
            e.printStackTrace();
             throw  new CustomizeException(CustomizeErrorCode.FILE_UPLOAD_ERROR);
        }
    }

    @Override
    public ResultDTO avatarUpload(MultipartFile file){
        if(file!=null){
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                String oldFileName = file.getOriginalFilename();
                //上传文件，随机名称，";"分号隔开
                String fileName =  UUID.randomUUID() + "." + StringUtils.substringAfterLast(oldFileName, ".");
                //判断该路径是否存在,如果不存在则创建该路径
                if (!client.doesBucketExist(properties.getBucket())) {
                    client.createBucket(properties.getBucket());
                    CreateBucketRequest createBucketRequest = new CreateBucketRequest(properties.getBucket());
                    createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                    client.createBucket(createBucketRequest);
                }

                //图片存放地址
                String fileUrl=properties.getDir()+"/avatar/"+fileName;
                PutObjectResult result = client.putObject(properties.getBucket(),fileUrl,inputStream);

                //设置Url过期时间为10年
                Date expiration =new Date(System.currentTimeMillis() + 36001 * 1000 * 24 * 365 * 10);
                URL url=client.generatePresignedUrl(properties.getBucket(),fileUrl,expiration);

//                保存图像信息
                if (authUtils.getuser()!=null){
                    UserInfo userInfo = userInfoService.queryuserinfo(Objects.requireNonNull(authUtils.getuser()));
                    userInfo.setAvatarUrl(url.toString()).setGmtModified(new Date());
                    userInfoService.updateById(userInfo);
                }
                return  ResultDTO.okOf(url.toString());
            } catch (Exception e) {
                log.error(e.getMessage());
                return ResultDTO.errorOf(CustomizeErrorCode.FILEUPLOAD_REEOR);
            }finally{
                try{
                    if (inputStream!= null){
                        inputStream.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return ResultDTO.errorOf(CustomizeErrorCode.FILEUPLOAD_REEOR);
    }

    @Override
    public FileDTO fileUpload(MultipartFile file) {
        if (!file.isEmpty()) {
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                //上传文件的源文件名
                String oldFileName = file.getOriginalFilename();
                //处理后的文件名
                String fileName = UUID.randomUUID() + "." + StringUtils.substringAfterLast(oldFileName, ".");

                //判断该路径是否存在,如果不存在则创建该路径
                if (!client.doesBucketExist(properties.getBucket())) {
                    client.createBucket(properties.getBucket());
                    CreateBucketRequest createBucketRequest = new CreateBucketRequest(properties.getBucket());
                    createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                    client.createBucket(createBucketRequest);
                }

                String fileUrl=properties.getDir()+fileName;
                PutObjectResult result = client.putObject(properties.getBucket(),fileUrl,inputStream);

                //设置Url过期时间为10年
                URL url=client.generatePresignedUrl(properties.getBucket(),fileUrl,new Date(System.currentTimeMillis() + 36001 * 1000 * 24 * 365 * 10));
                return new FileDTO().setMessage("上传成功").setUrl(url.toString()).setSuccess(1);
            }  catch (Exception e) {
                log.error(e.getMessage());
                return new FileDTO().setMessage(e.getMessage()+"上传失败").setSuccess(0);
            }finally{
                try{
                    if (inputStream!= null){
                        inputStream.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }

            }
        }
        return null;
    }
}
